package pkg

import (
	"bytes"
	"context"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"log"
	"strconv"
	"sync"
	"yk-travel-social/common/model/es"
	"yk-travel-social/common/model/mysql"
)

func indexExists(index string) (bool, error) {
	request := esapi.IndicesExistsRequest{
		Index: []string{index},
	}

	do, err := request.Do(context.Background(), es.ES)
	if err != nil {
		return false, err
	}

	defer do.Body.Close()
	return true, nil
}

func indexDel(index string) error {
	request := esapi.IndicesDeleteRequest{
		Index: []string{index},
	}

	do, err := request.Do(context.Background(), es.ES)
	if err != nil {
		return err
	}

	defer do.Body.Close()
	return nil
}

func indexCreate(index string) error {
	exists, err := indexExists(index)
	if err != nil {
		return err
	}
	if exists {
		indexDel(index)
	}

	mapping := `{
		"mappings": {
        	"properties": {
				"ScenicSpotName": {
					"type": "text",
					"analyzer": "ik_max_word"
				}
        	}
    	}		
	}`

	request := esapi.IndicesCreateRequest{
		Index: "travel",
		Body:  bytes.NewReader([]byte(mapping)),
	}

	do, err := request.Do(context.Background(), es.ES)
	if err != nil {
		return err
	}

	defer do.Body.Close()

	return nil
}

func SyncEs(list []*mysql.ScenicSpot) (string, error) {
	err := indexCreate("travel")
	if err != nil {
		return "", err
	}

	wg := sync.WaitGroup{}

	for _, Travel := range list {
		wg.Add(1)

		go func(Travel *mysql.ScenicSpot) {
			defer wg.Done()

			// Build the request body.
			data, err := json.Marshal(Travel)
			if err != nil {
				log.Fatalf("Error marshaling document: %s", err)
			}

			// Set up the request object.
			req := esapi.IndexRequest{
				Index:      "travel",
				DocumentID: strconv.Itoa(int(Travel.ID)),
				Body:       bytes.NewReader(data),
				Refresh:    "true",
			}

			// Perform the request with the client.
			res, err := req.Do(context.Background(), es.ES)
			if err != nil {
				log.Fatalf("Error getting response: %s", err)
			}
			defer res.Body.Close()

		}(Travel)
	}
	wg.Wait()
	return "同步成功", nil
}
